package cn.demoncat.util.mybatis.plus;

import cn.demoncat.util.lang.entity.PageParam;
import cn.demoncat.util.lang.entity.Pager;
import cn.demoncat.util.mybatis.plus.config.DynamicTableHolder;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * MybatisPlus 工具
 *
 * @author 延晓磊
 * @since 2021年08月23日
 */
public class MybatisPlusUtil {

    /**
     * 分页参数转换
     *
     * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
     * @param pageSize  	页长：null/0/负数 == 10，最大10000
     * @param orders  	    排序
     * @param <T>
     * @return page
     *
     * @author 延晓磊
     * @since 2021年08月23日
     */
    public static <T> Page<T> toPage(Integer pageNum, Integer pageSize, OrderItem ...orders){
        return toPage(pageNum, pageSize, (ArrayUtils.isEmpty(orders) || orders[0] == null) ? null : Arrays.asList(orders));
    }

    /**
     * 分页参数转换
     *
     * @param pageNum		页码：null/0 == 首页，负数 == 尾页，大于页数 == 尾页
     * @param pageSize  	页长：null/0/负数 == 10，最大10000
     * @param orders  	    排序
     * @param <T>
     * @return page
     *
     * @author 延晓磊
     * @since 2021年08月23日
     */
    public static <T> Page<T> toPage(Integer pageNum, Integer pageSize, List<OrderItem> orders){
        // 更正化分页参数
        PageParam pp = Pager.initPageParams(pageNum, pageSize);
        // 分页
        Page<T> page = new Page<>(pp.getPageNum(), pp.getPageSize());
        // 排序
        return CollectionUtils.isNotEmpty(orders) ? page.addOrder(orders) : page;
    }


    /**
     * 分页结果转换
     *
     * @param page
     * @param <T>
     * @return pager
     *
     * @author 延晓磊
     * @since 2021年08月23日
     */
    public static <T> Pager<T> toPager(IPage<T> page){
        Pager<T> pager = new Pager<>();
        pager.setPageNum((int) page.getCurrent());
        pager.setPageSize((int) page.getSize());
        pager.setPageCount((int) page.getPages());
        pager.setTotalCount(page.getTotal());
        pager.setPageStart(page.offset());
        pager.setList(page.getRecords());
        return pager;
    }

    /**
     * QueryWrapper 转 LambdaQueryWrapper
     *
     * @param query QueryWrapper
     * @param <T>
     * @return LambdaQueryWrapper
     *
     * @author 延晓磊
     * @since 2021年08月23日
     */
    public static <T>LambdaQuery<T> toLambda(Query<T> query){
        if (query == null) {
            return new LambdaQuery<>();
        }
        return query.lambda();
    }

    /**
     * 添加动态表映射
     *
     * <pre>
     *     场景：操作动态表
     *     使用：添加动态表映射(线程有效) > 执行动态表操作
     *     注意：如果表不存在，在操作时会报错 SQLSyntaxErrorException
     * </pre>
     *
     * @param table     静态表名
     * @param suffix    动态表名后缀
     *
     * @author 延晓磊
     * @since 2021年09月14日
     */
    public static void addDynamicTable(String table, String suffix){
        DynamicTableHolder.set(table, suffix);
    }

    /**
     * 移除动态表映射
     *
     * <pre>
     *     场景：操作动态表后，操作非动态表（同源）
     *     使用：移除动态表映射(线程有效) > 执行非动态表操作
     * </pre>
     *
     * @param table     静态表名
     *
     * @author 延晓磊
     * @since 2021年09月14日
     */
    public static void removeDynamicTable(String table){
        DynamicTableHolder.remove(table);
    }

    /**
     * 获取OrderItem
     *
     * @param order	默认排序
     * @param sort	排序方式：10 X升序，11 X逆序
     * @param columns	排序字段：{1:id,2:name}
     * @return
     */
    public static OrderItem getOrder(OrderItem order, String sort, Map<String,String> columns){
        if (StringUtils.isNotBlank(sort)) {
            boolean asc = '0' == sort.charAt(sort.length() - 1);
            String column = columns.get(sort.substring(0, sort.length()-1));
            if (StringUtils.isNotBlank(column)) {
                return asc ? OrderItem.asc(column) : OrderItem.desc(column);
            }
        }
        return order;
    }
}
